using System;
using System.Text.RegularExpressions;

using Impact.Infrastructure.Configuration;
using Impact.Model.Service;

using StructureMap;
using System.Collections.Generic;

namespace Impact.Model.Objects
{
    /// <summary>
    /// extensions to the SubSonic object Article
    /// </summary>
    public partial class Article
    {


        /// <summary>
        /// set default values specific to articles
        /// </summary>
        public new void SetDefaults()
        {
            base.SetDefaults();

            this.AllowComments = true;
        }



        #region Foreign Key Relationships

        /// <summary>
        /// One to Many - Returns the Category for this Article
        /// </summary>
        public ArticleCategory Category
        {
            get
            {
                if ( category == null )
                {
                    ICategoryService categoryService = ObjectFactory.GetInstance<ICategoryService>();
                    category = categoryService.FetchByID( CategoryId );
                }
                return category;
            }
            set
            {
                SetColumnValue( "CategoryId", value.CategoryId );
            }
        }
        private ArticleCategory category;


        /// <summary>
        /// One to Many - Returns ArticleComments
        /// </summary>
        public ArticleCommentCollection Comments
        {
            get
            {
                if ( comments == null )
                {
                    IArticleService articleService = ObjectFactory.GetInstance<IArticleService>();
                    comments = articleService.FetchComments( ArticleId );
                }
                return comments;
            }
        }
        private ArticleCommentCollection comments;

        /// <summary>
        /// Get the collection of tags associated with this article
        /// </summary>
        public ArticleTagCollection Tags
        {
            get
            {
                if ( tags == null )
                {
                    IArticleService articleService = ObjectFactory.GetInstance<IArticleService>();
                    tags = articleService.FetchTags( ArticleId );
                }
                return tags;
            }
        }
        private ArticleTagCollection tags;

        #endregion

        /// <summary>
        /// the folder that has been configured to use to denote articles in the URL
        /// </summary>
        public static string ArticleFolder
        {
            get
            {
                IConfigProvider config = ObjectFactory.GetInstance<IConfigProvider>();
                return config.Settings.ArticleFolder;
            }
        }

        /// <summary>
        /// Returns true if the article passed in is a valid object and can be used
        /// </summary>
        /// <param name="article"></param>
        /// <returns></returns>
        public static bool IsValid( Article article )
        {
            return article != null && article.ArticleId > 0;
        }

        /// <summary>
        /// provides a user-friendly description of this object
        /// </summary>
        public override string ToString()
        {
            return this.Title;
        }

        /// <summary>
        /// retrieve an article based on the Url used to show that article
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static Article FetchByUrl( Uri url )
        {
            Article output = null;
            Match m = Regex.Match( url.PathAndQuery, @"/\d+/" );
            string param = m.Value.Replace( "/", string.Empty );
            int articleId = -1;
            if ( Int32.TryParse( param, out articleId ) )
            {
                IArticleService articleService = ObjectFactory.GetInstance<IArticleService>();
                output = articleService.FetchByID( articleId );
            }
            return output;
        }

    }
}
